#ifndef EXAMPLE_H
#define EXAMPLE_H

#include <string>
/*
class Example { // tolua_export

private:

	std::string name;
	int number;

public:
	//tolua_begin
	Example():number(0){}
	void set_number(int number);
	void set_name(std::string name);

	

	std::string get_name();
	int get_number();
};
// tolua_end

//extern Example exobj;	// tolua_export
*/
#define MACRO1 30

enum{
	EnumValue1 = 10,
	EnumValue2,
};

int an_integer = 15;
const char *an_str = "zhangwei";
int an_intarr[] = {1, 2, 3, 4, 5};

const char *saysomething(bool say = false)
{
	if(say)
		return "you want me say something";
	else
		return "I dont want to say something";
}

void change2nd(int arr[])
{
	arr[1] = 3;
}

const char *overloaded_func1(int)
{
	return "overloaded_func1(int)";
}

const char *overloaded_func1(double)
{
	return "overloaded_func1(double)";
}

const char *overloaded_func1(char *str)
{
	str[0] = 'h';
	return "overloaded_func1(char *)";
}

void my_swap(int &a, int &b)
{
	int temp = a;
	a = b;
	b = temp;
}

void break_point()
{
	_asm int 3;
}

typedef struct {
	int x[10];
	int y[10];
} Example; 

Example example;

class Base
{
public:
	int i;
	std::string str;
};

class Base1
{
public:
	const char *say()
	{
		return "I'm saying";
	}
};

class Derived : public Base, public Base1
{
public:
	Derived(int i):new_i(i){}
	~Derived()
	{
		_asm int 3;
	}
	int new_i;
	std::string new_str;
};

const char *test_inher(const Base &obj)
{
	return obj.str.c_str();
}

class Point {
public:
	static int n;    // represents the total number of created Points
	static int get_n()    // static method
	{
		return n;
	}

	double x;        // represents the x coordinate
	double y;        // represents the y coordinate

	static char* className (void)   // returns the name of the class
	{
		return "Point";
	}

	Point (void):x(0),y(0){++n;}                  // constructor 1
	Point (double px, double py):x(px),y(py){++n;}          // constructor 2
	Point(const Point &rhs):x(rhs.x),y(rhs.y){++n;}
	virtual ~Point (void){--n;}                         // destructor

	Point &add (const Point& other)              // add points, returning another one
	{
		x += other.x;
		y += other.y;
		return *this;
	}
	Point &operator+(const Point &other)
	{
		return add(other);
	}
};

int Point::n = 0;

class ColorPoint : public Point {
public:
	int red;      // red color component [0 - 255]
	int green;    // green color component [0 - 255]
	int blue;     // blue color component [0 - 255]

	ColorPoint (double px, double py, int r, int g, int b):
		Point(px, py), red(r), green(g), blue(b){}

	int &operator[] (int index)
	{
		if(index == 0)
		{
			return red;
		}
		else if(index == 1)
		{
			return green;
		}
		else
		{
			return blue;
		}
	}

	operator long()
	{
		return red<<16 | green<<8 | blue;
	}
};

class Position {
private:
	int x;
	int y;
	friend void position_set(Position* pos, int x, int y)
	{
		pos->x = x;
		pos->y = y;
	}
public:
	void set_x(int x)
	{
		this->x = x;
	}
	int get_x()
	{
		return x;
	}
	void set_y(int y)
	{
		this->y = y;
	}
	int get_y()
	{
		return y;
	}
	void getpos(int *x=0, int *y=0)
	{
		*x = this->x;
		*y = this->y;
	}
} ;

Position* position_create()
{
	return new Position;
}

Position pos;

#include <lua.hpp>

const char *show_lua_state(lua_State *L)
{
	static const size_t buflength = 2048;
	static char buf[buflength];
	size_t cursor = 0;

	int top = lua_gettop(L);
	cursor += sprintf_s(buf+cursor, buflength-cursor, "\ttop: %d\n", lua_gettop(L));
	for(int i = top; i > 0; --i)
	{
		int type = lua_type(L, i);
		cursor += sprintf_s(buf+cursor, buflength-cursor, "\t\t\t%d\t%s\t", i-top-1, lua_typename(L, type));
		if(cursor >= buflength) break;

		switch(type)
		{
		case LUA_TBOOLEAN:
			cursor += sprintf_s(buf+cursor, buflength-cursor, lua_toboolean(L, i) ? "true" : "false");
			break;
		case LUA_TSTRING:
			cursor += sprintf_s(buf+cursor, buflength-cursor, lua_tostring(L, i));
			break;
		case LUA_TTABLE:
			cursor += sprintf_s(buf+cursor, buflength-cursor, "length: %d", lua_objlen(L, i));
			break;
		default:
			cursor += sprintf_s(buf+cursor, buflength-cursor, "unknown type:%d", lua_type(L, i));
		}
		if(cursor >= buflength) break;

		cursor += sprintf_s(buf+cursor, buflength-cursor, "\n");
		if(cursor >= buflength) break;
	}
	return buf;
}

class Foo
{
private:
	int m_i;
public:
	int i()
	{
		return m_i;
	}
	void setI(int i)
	{
		this->m_i = i;
	}
};
#endif